// This File is part of Innovation Foundry's "QualityHelper Project"
//
// Copyright  2009 Innovation Foundry Pty Ltd
// All rights reserved
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA  02110-1301 USA
// or alternatively it may be downloaded from <http://www.gnu.org/licenses/>.

using System;
using System.Windows;
using System.Windows.Browser;


namespace InnovationFoundry.QualityHelper.Silverlight.Controls.Zoom
{

	public class MouseWheelEventArgs : EventArgs {
		private double delta;
		private bool handled = false;
        private HtmlEventArgs htmlEventArgs;

        public HtmlEventArgs HtmlEventArgs {
            get { return htmlEventArgs; }
            set { htmlEventArgs = value; }
        }

		public MouseWheelEventArgs(double delta) {
			this.delta = delta;
		}

		public double Delta {
			get { return this.delta; }
		}

		public bool Handled {
			get { return this.handled; }
			set { this.handled = value; }
		}
	}

	public class MouseWheelHelper {

		public event EventHandler<MouseWheelEventArgs> Moved;
		private static Worker worker;
		private bool isMouseOver = false;

		public MouseWheelHelper(FrameworkElement element) {

			if (MouseWheelHelper.worker == null)
				MouseWheelHelper.worker = new Worker();

			MouseWheelHelper.worker.Moved += this.HandleMouseWheel;

			element.MouseEnter += this.HandleMouseEnter;
			element.MouseLeave += this.HandleMouseLeave;
			element.MouseMove += this.HandleMouseMove;
		}

		private void HandleMouseWheel(object sender, MouseWheelEventArgs args) {
			if (this.isMouseOver)
				this.Moved(this, args);
		}

		private void HandleMouseEnter(object sender, EventArgs e) {
			this.isMouseOver = true;
		}

		private void HandleMouseLeave(object sender, EventArgs e) {
			this.isMouseOver = false;
		}

		private void HandleMouseMove(object sender, EventArgs e) {
			this.isMouseOver = true;
		}

		private class Worker {

			public event EventHandler<MouseWheelEventArgs> Moved;

			public Worker() {

				if (HtmlPage.IsEnabled) {
					HtmlPage.Window.AttachEvent("DOMMouseScroll", this.HandleMouseWheel);
					HtmlPage.Window.AttachEvent("onmousewheel", this.HandleMouseWheel);
					HtmlPage.Document.AttachEvent("onmousewheel", this.HandleMouseWheel);
				}

			}

			private void HandleMouseWheel(object sender, HtmlEventArgs args) {
				double delta = 0;

				ScriptObject eventObj = args.EventObject;

				if (eventObj.GetProperty("wheelDelta") != null) {
					delta = ((double)eventObj.GetProperty("wheelDelta")) /120;


					if (HtmlPage.Window.GetProperty("opera") != null)
						delta = -delta;
				}
				else if (eventObj.GetProperty("detail") != null) {
					delta = -((double)eventObj.GetProperty("detail"))/3;

					if (HtmlPage.BrowserInformation.UserAgent.IndexOf("Macintosh") != -1)
						delta = delta * 3;
				}

				if (delta != 0 && this.Moved != null) {
					MouseWheelEventArgs wheelArgs = new MouseWheelEventArgs(delta);
                    wheelArgs.HtmlEventArgs = args;
					this.Moved(this, wheelArgs);

                    if (wheelArgs.Handled) {
                        args.PreventDefault();
                        args.EventObject.SetProperty("returnValue", false);
                    }
				}
			}
		}
	}
}
